package com.example.lib_common.livedata_eventbus

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
//这个livedata在testActivity中测试了，为了解决数据倒灌的问题，不过这里支持粘性事件和非粘性事件的版本
object LiveEventBus2 {
     val stickyEvents = mutableMapOf<String, MutableLiveData<Any>>()
     val normalEvents = mutableMapOf<String, MutableLiveData<Event<*>>>()

    // 发送粘性事件（新观察者会立即收到）
    fun <T> postSticky(key: String, value: T) {
        if (!stickyEvents.containsKey(key)) {
            stickyEvents[key] = MutableLiveData()
        }
        stickyEvents[key]?.value = value
    }

    // 发送普通事件（新观察者不会收到）
    fun <T> postNormal(key: String, value: T) {
        if (!normalEvents.containsKey(key)) {
            normalEvents[key] = MutableLiveData()
        }
        normalEvents[key]?.value = Event(value)
    }

    // 获取粘性事件LiveData
    fun <T> getStickyLiveData(key: String, type: Class<T>): LiveData<T> {
        if (!stickyEvents.containsKey(key)) {
            stickyEvents[key] = MutableLiveData()
        }
        @Suppress("UNCHECKED_CAST")
        return stickyEvents[key] as LiveData<T>
    }

    // 获取普通事件LiveData
    fun <T> getNormalLiveData(key: String, type: Class<T>): LiveData<Event<T>> {
        if (!normalEvents.containsKey(key)) {
            normalEvents[key] = MutableLiveData()
        }
        @Suppress("UNCHECKED_CAST")
        return normalEvents[key] as LiveData<Event<T>>
    }
/*
这段代码定义了一个泛型类 Event<T>，它的主要作用是封装事件内容并跟踪事件是否已被处理。这在事件总线模式中非常有用，特别是为了防止事件被多次消费。以下是详细解析：
防止数据倒灌

核心功能：
封装事件内容
构造函数接收一个 content: T 参数，保存要传递的事件数据。
处理状态跟踪
private var hasBeenHandled = false 标记事件是否已被处理过。
安全获取事件内容的方法：
getContentIfNotHandled(): T?
如果事件未被处理过，返回内容并标记为已处理；已处理过则返回 null。
用途：确保事件只被消费一次（例如点击事件避免重复响应）。
peekContent(): T
直接返回内容不修改处理状态。
用途：当需要多次读取内容或只观察不消费时（如日志记录）。
在事件总线中的用途：
普通事件：通过 Event 包装后发送，确保新注册的观察者不会收到旧事件。
粘性事件：直接发送原始数据（不包装），新观察者会立即收到最后一次发送的值。
 */
    class Event<T>(private val content: T) {
        private var hasBeenHandled = false

        fun getContentIfNotHandled(): T? {
            return if (hasBeenHandled) {
                null
            } else {
                hasBeenHandled = true
                content
            }
        }

        fun peekContent(): T = content
    }
}